package org.chnxi.study.serialize.jackson;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;

import java.text.SimpleDateFormat;

public class JSONUtil {

    private static JsonMapper mapper = new JsonMapper();

    static {
        //对象的所有字段全部列入
        mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        //取消默认转换timestamp的形式
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS , false);
        // 忽略空Bean转JSON的错误
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS , false);
        // 统一日期格式
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * 转换对象到JSON格式，转换失败时抛出RuntimeException异常
     * @param t
     * @param <T>
     * @return
     */
    public static <T> String object2String(T t){
        return object2StringPretty(t,false);
    }

    /**
     * 可以将输出的JSON进行美化
     * @param t
     * @param state 是否使用美化格式
     * @param <T>
     * @return
     */
    public static <T> String object2StringPretty(T t , boolean state){
        if(t == null){
            return null;
        }

        try {
            return t instanceof String ? (String)t :
                    state == true ? mapper.writerWithDefaultPrettyPrinter().writeValueAsString(t) :
                            mapper.writeValueAsString(t);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("转换JSON发生错误："+e.getMessage() , e);
        }
    }

    /**
     * 字符串转对象
     * @param json
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T string2Object(String json , Class<T> clazz){
        if(json == null || json.trim().length() < 1 || clazz == null){
            return null;
        }

        try {
            return clazz.equals(String.class) ? (T) json : mapper.readValue(json , clazz);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("转换对象发生错误:"+e.getMessage() , e);
        }
    }

    /**
     * 将JSON字符串转换为集合对象
     * @param json
     * @param typeReference
     * @param <T>
     * @return
     */
    public static <T> T string2Object(String json , TypeReference<T> typeReference){
        if(json == null || json.trim().length() < 1 || typeReference == null){
            return null;
        }
        try {
            return typeReference.getType().equals(String.class) ? (T) json : mapper.readValue(json , typeReference);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("转换集合对象发生错误:"+e.getMessage() , e);
        }
    }

    public static <T> T String2Object(String json , Class<?> collectionClazz, Class<?>... elementClazzes){
        if(json == null || json.trim().length() < 1 || collectionClazz == null || elementClazzes.length < 1){
            return null;
        }

        JavaType javaType = mapper.getTypeFactory().constructParametricType(collectionClazz, elementClazzes);
        try {
            return mapper.readValue(json , javaType);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("转换集合对象发生错误:"+e.getMessage() , e);
        }
    }

}
